// ==UserScript==
// @name         sinopec - genSql
// @namespace    http://tampermonkey.net/
// @version      2025-07-15
// @description  genSql
// @author       tako
// @match        https://kpi.dsp.sinopec.com/*
// ==/UserScript==

(function () {
    'use strict';

    createButton();

    // 创建按钮
    function createButton() {
        const btn = document.createElement('button');
        btn.textContent = 'SQL';
        btn.style.position = 'fixed';
        btn.style.top = '220px';
        btn.style.right = '0px';
        btn.style.zIndex = '9999';
        btn.style.padding = '10px 13px';
        btn.style.backgroundColor = '#4CAF50';
        btn.style.color = 'white';
        btn.style.border = 'none';
        btn.style.borderRadius = '4px';
        btn.style.cursor = 'pointer';
        
        btn.addEventListener('click', function () {
            btn.disabled = true;
            btn.style.backgroundColor = '#ccc';
            // 异步操作
            doWork().catch(error => {
                alert('生成SQL失败! ' + error);
            }).finally(() => {
                btn.disabled = false;
                btn.style.backgroundColor = '#4CAF50';
            })
        });

        document.body.appendChild(btn);
    }

    async function doWork() {
        console.log('开始生成SQL语句...');
        // 模拟异步操作
        // await new Promise(resolve => setTimeout(resolve, 3000));
        const kpiCodeCOM = document.getElementById('kpiCode');
        if (!kpiCodeCOM) {
            throw new Error('未找到KPI Code输入框，请检查页面元素。');
        }
        let kpiCode = kpiCodeCOM.value;
        let kpiData = await getKpiDataByCode(kpiCode)
        let kpiName = kpiData.kpiName;
        let defineFormula = kpiData.defineFormula;
        let kpiDesc = kpiData.kpiDesc;
        let kpiDims = kpiData.dimension.map(item => item.fieldName).join(' ');
        let kpiMDim = kpiData.measure.map(item => item.fieldName).join(' ');
        let { dims_str, sql, final_str } = gen(kpiDims, kpiMDim)
        console.log(dims_str);
        console.log(sql);
        let join = [`#### ${kpiName}`, `- ID: ${kpiCode}`, `- 指标公式: ${defineFormula}`, `- 取数公式: ${kpiDesc}`, final_str].join('\n');
        navigator.clipboard.writeText(join);
        const succes = insertSqlToPage(sql);
        if (!succes) {
            throw new Error('未找到CodeMirror实例，无法插入SQL语句。请手动复制粘贴。');
        }
    }

    function insertSqlToPage(value) {
        // 查找页面中的所有CodeMirror实例
        const codeMirrors = document.querySelectorAll('.CodeMirror');
        if (codeMirrors.length > 0) {
            // 获取第一个CodeMirror实例的编辑器对象
            const cm = codeMirrors[0].CodeMirror;
            if (cm) {
                cm.setValue(value);
                return true;
            }
        }
        return false;
    }

    function print_dims(dict, dims, m_Dim) {
        let dims_list_str = '';
        dims.trim().split(/\s+/).forEach(dim => {
            dims_list_str += `${dim.trim()}(${dict[dim.trim()]}) `;
        });
        let m_Dim_str = `${m_Dim.trim()}(${dict[m_Dim.trim()]})`;
        return `- 维度: ${dims_list_str}\n- 度量: ${m_Dim_str}`;
    }

    function gen_sql(dict, dims, m_Dim) {
        let dims_list = [];
        dims.trim().split(/\s+/).forEach(dim => {
            dims_list.push(dict[dim.trim()]);
        });
        let dims_str = dims_list.join(', ');
        let m_Dim_str = dict[m_Dim.trim()];

        const year_dim = 'GHFISCYEAR';
        let order_dims = '';
        if (dims_list.includes(year_dim)) {
            let new_list = [];
            dims_list.forEach(dim => {
                if (dim !== year_dim) {
                    new_list.push(dim);
                }
            });
            order_dims = new_list.join(', ') + ` ASC, ${year_dim} DESC`;
        } else {
            order_dims = dims_list.join(', ');
        }
        return `SELECT ${dims_str}, SUM(${m_Dim_str}) AS result \nFROM "_SYS_BIC"."SINOPEC.ZBYY.CWYY.004_QMYS.H/F7AS_ZB_H_CW0003" \nWHERE \nGROUP BY ${dims_str} \nORDER BY ${order_dims}`;
    }

    function gen(dims, m_Dim) {
        const dict = { '源系统': 'GHLOGSYS', '公司代码': 'GHYGSDM', '基本计量单位': 'GHBASEUOM', '成本控制范围': 'GHCOAREA', '产品类别': 'GHYCPLB', '过帐级别': 'GHPLEVEL', '客户分类': 'GHCUSTCLASS', '凭证货币': 'GHDOCCURRCY', '客户': 'GHF00CUST', '记帐期间': 'GHFISCPER3', '会计年度变式': 'GHFISCVARNT', '会计年度': 'GHFISCYEAR', '工厂': 'GHYGC', '科研费用支出类别': 'GHG0KYFYLB', '企业物料编码': 'GHG0QYWL', '生产版本': 'GHYSCBB', '其他应收应付款分类': 'GHG0WLFL', '其他往来分类': 'GHG0WLFL7', '企业资产处理事务类型': 'GHG0ZCCLLX', '财务销售方式': 'GHGFXSFS', '销售去向': 'GHYXSQX', '折算差异': 'KHK0ZSCY', '本位币': 'GHLOCCURRCY', '月份': 'GHMONTH', '合并利润中心': 'GHPRCTR', 'BW 增量处理： 更新模式': 'GHRECORDMODE', '安全生产费明细': 'GHYAQSC', '安全生产费提取环节': 'GHYAQSCFTQ', '安全生产费用途': 'GHYAQSCFYT', 'BCS分子公司属性': 'GHYBCSCOMSX', '本方地区': 'GHYBFGJDQ', '业务范围': 'GHYBKBH', '编号': 'GHYBMBH', '订单编号（公司）': 'GHYCBDD', '成本要素': 'GHYCBYS', '成本中心经营类型': 'GHYCBZCJYLX', '成本中心': 'GHYCBZX', '成本中心类别': 'GHYCBZXLB', '成本中心类型': 'GHYCBZXLX', '重分类标识': 'GHYCFLBS', '采购成本明细': 'GHYCGCBMX', '采购服务类型': 'GHYCGFWLX', '采购来源-指标库': 'GHYCGLYZBK', '存货大类': 'GHYCHDL', '存货分类': 'GHYCHFL', '存货来源': 'GHYCHLY', '测井测试项目': 'GHYCJCSXM', '存款期限': 'GHYCKQX', '产品及劳务': 'GHYCPJLW', '产品及劳务类别': 'GHYCPLWLB', '长期应付款分类': 'GHYCQYFKFL', '长期应付款分类X': 'GHYCQYFKFLX', '长期职工薪酬明细': 'GHYCQZGMX', '长期股权投资分类': 'GHYCTFL', '长期待摊费用类型': 'GHYCTLX', '长期股权增减变动类型': 'GHYCTZJBD', '财务费用明细': 'GHYCWFYMX', '稠油热采类别': 'GHYCYRCLB', '持有至到期投资类型': 'GHYCYZDQTZ', '债务重组损益分类': 'GHYCZFL', '订单类别': 'GHYDDLB', '对方板块': 'GHYDFBK', '动力类别': 'GHYDLLBZBK', '地区': 'GHYDQ', '待摊进货产品类别': 'GHYDTJHCP', '待摊进货费类型': 'GHYDTJHLX', '待摊进货 运输方式': 'GHYDTJHYS', '报表单位': 'GHYDWBH', '单位性质': 'GHYDWXZ', '对象分类': 'GHYDXFL', '抵消性质': 'GHYDXXZ', '递延所得税转出方向': 'GHYDYSDSFX', '递延收益明细': 'GHYDYSYMX', '递延收益类型': 'GHYDYSYLX', '递延所得税资产/负债分类': 'GHYDYZFFL', '付款方式补充': 'GHYFKFSBC', '费用类型': 'GHYFYLXZBK', '应交税费来源': 'GHYFYLY', '费 用要素': 'GHYFYYS', '自定义辅助核算01': 'GHYFZ01', '辅助核算02': 'GHYFZ02', '自定义辅助核算06': 'GHYFZ06', '自定义辅助核算07': 'GHYFZ07', '自定义辅助核算08': 'GHYFZ08', '自定义辅助核算09': 'GHYFZ09', '自定义辅助核算11': 'GHYFZ11', '自定义辅助核算12': 'GHYFZ12', '工程物资分类': 'GHYGCFL', '工程类别': 'GHYGCLB', '工程项目类型': 'GHYGCXMLX', '股东权益来源': 'GHYGDQY', '股东性质': 'GHYGDXZ', '股东权益增减变动类型': 'GHYGDZJBD', '关联交易类型': 'GHYGLJYLX', '管输介质分类': 'GHYGSJZFL', '公允价值变动损益 明细': 'GHYGYBD', '挂职干部经费支出分类': 'GHYGZGBJF', '合同号': 'GHYHQHTBH', '或有事项明细': 'GHYHYSXMX', '坏账计提方式': 'GHYHZJTFS', '指标': 'GHYINDID', '井别': 'GHYJB', '非经常性损益明细': 'GHYJCSY', '经济用途': 'GHYJJYT', '借款类型': 'GHYJKLX', '借款费用列支方向': 'GHYJKLZ', '金融衍生品业务类型': 'GHYJRYS', '关联交易业务类型--集 团': 'GHYJTGLJYLX', '计提日': 'GHYJTR', '井下作业项目': 'GHYJXZYXM', '交易性金融资产类型': 'GHYJYZC', '减值准备增减变动类型': 'GHYJZZJBD', '库存增减变动类型': 'GHYKCBDLX', '可供出售金融资产类型': 'GHYKGCS', '客户行业': 'GHYKHHY', '(企业)总帐科目': 'GHYKJKM', '科目编号': 'GHYKMBH', '科目明细': 'GHYKMMX', '科目增减类型': 'GHYKMZJLX', ' 炼化工程劳务类型': 'GHYLHLWLX', '炼化装置': 'GHYLHZZ', '利润分配明细': 'GHYLRFPMX', '利润中心': 'GHYLRZX', '利润中心类别-销售': 'GHYLRZXLB', '利息收入分类（金融企业）': 'GHYLXSRFL', '利息支出分类（金融企业）': 'GHYLXZCFL', '模型选用': 'GHYMDSEL', '内部编号': 'GHYNBBH', '内部拨款明细': 'GHYNBBKMX', '内部单位编号': 'GHYNBDWBH', '组织单 位': 'GHYORGID', '贸易伙伴': 'GHYPCOMPANY', '伙伴功能范围': 'GHYPFUNAREA', '票据号': 'GHYPJH', '票据类型': 'GHYPJLX', '凭证类型': 'GHYPZLX', '区块': 'GHYQK', '区块产品 类别': 'GHYQKCPLB', '其他货币资金类型': 'GHYQTHBZJLX', '轻烃回收产品': 'GHYQTHSCP', '其他业务收支明细': 'GHYQTSZ', '其他综合收益来源': 'GHYQTZHSYLY', '其他债权投资类型': 'GHYQTZQ', '企业级成本要素': 'GHYQYCBYS', '企业级产品大类': 'GHYQYCPLB', '供应商': 'GHYQYGYS', '企业级炼化装置': 'GHYQYLHZZ', '移动类型': 'GHYYDLX', '行号': 'GHYRECID', '融资业务类型': 'GHYRZYWLX', '生产中心': 'GHYSCZX', '生产装置': 'GHYSCZZ', '段': 'GHYSEGMENT', '施工方法': 'GHYSGFF', '实货/保值': 'GHYSHBZ', '收缴部门类型': 'GHYSJBMLX', '数据类型': 'GHYSJLX', 'BW数据来源': 'GHYSJLYBW', '数据来源': 'GHYSJLYZBK', '税种': 'GHYSLLB', '会计凭证类型': 'GHYSPHKLX', '三新业务分类': 'GHYSXYWFL', '所有权收到限制的原因': 'GHYSXYY', '事业部': 'GHYSYB', '事业部属性': 'GHYSYBSX', '总部统计指标': 'GHYTJZB', '投料方式': 'GHYTLFS', '提升物分类': 'GHYTSWFL', '投资类型': 'GHYTZLX', '投资收益类型': 'GHYTZSY', 'CO业务类型': 'GHYVRGNG', '企业级WBS元素': 'GHYWBSQY', 'WBS要素': 'GHYWBSYS', '委托贷款分类': 'GHYWDFL', '对方单位编码': 'GHYWLDW', '往来 单位地区': 'GHYWLDWDQ', '往来单位属性': 'GHYWLDWSX', '物料类别': 'GHYWLLB', '物料组分类': 'GHYWLZFL', '委托金融机构': 'GHYWTJG', '无形资产特定分类': 'GHYWXZCFL', '消费 税明细': 'GHYXFSMX', '现金流向': 'GHYXJLX', '修理资产分类': 'GHYXLZCFL', '项目': 'GHYXM', '项目增减变动类型': 'GHYXMBDLX', '项目编码描述': 'GHYXMBMDES', '项目大类': 'GHYXMDL', '项目地区': 'GHYXMDQ', '项目分类': 'GHYXMFL', '项目分类_指标库': 'GHYXMFLZBK', '项目类型': 'GHYXMLX', '销售方式': 'GHYXSFS', '销售渠道ERP': 'GHYXSQD', '信用减值损失明细': 'GHYXYJZMX', '研发支出类型': 'GHYYFZCLX', '银行名称': 'GHYYHMC', '油品管输线路': 'GHYYPGSLX', '油气处理对象': 'GHYYQCLDX', '衍生金融资产/负债分类': 'GHYYSGJFL', '应付股利分类': 'GHYYSGL', '应收利息分类': 'GHYYSLX', '油销专业中心': 'GHYYXZYZX', '营业外收支明细': 'GHYYYWSZMX', '总部分销渠道': 'GHYZBFXQD', '资产增减变动类型': 'GHYZCBD', '资产处置类型': 'GHYZCCZLX', '资产到期年月(日)': 'GHYZCDQNYZ', '资产分类': 'GHYZCFL', '资产减值损失明细': 'GHYZCJZSYMX', '资产租赁类型': 'GHZCZLLX', '资产使 用状态': 'GHYZCZT', '职工薪酬明细': 'GHYZGXCMX', '在建工程分类': 'GHYZJFL', '在建工程支出明细': 'GHYZJZCMX', '账龄': 'GHYZL', '租赁对方单位属性': 'GHYZLDFDWSX', '债券类型': 'GHYZQLX', '注入物分类': 'GHYZRWFL', '专项应付款分类': 'GHYZXYFKFL', '资源税类别': 'GHYZYSLB', '作业性质': 'GHYZYXZ', '装置互供': 'GHYZZHG', '增值税明细': 'GHYZZSMX', '增值税纳税人类型': 'GHYZZSNSRLX', '本期含税金额': 'KHK0BQHSJE', '本期金额': 'KHK0BQJE', '本期减少': 'KHK0BQJS', '本期数量': 'KHK0BQSL', '本期外币': 'KHK0BQWB', '本期增加': 'KHK0BQZJ', '减少数量': 'KHK0JSSL', '减少外币': 'KHK0JSWB', '累计含税金额': 'KHK0LJHSJE', '累计金额': 'KHK0LJJE', '累计减少': 'KHK0LJJS', '累计减少金额': 'KHK0LJJSJE', '累计数量': 'KHK0LJSL', '累计金额（外币）': 'KHK0LJWB', '累计增加': 'KHK0LJZJ', '累计增加金额': 'KHK0LJZJJE', '期初金额': 'KHK0QCJE', '期初数量': 'KHK0QCSL', '期初外币': 'KHK0QCWB', '期末金额': 'KHK0QMJE', '期末数量': 'KHK0QMSL', '期末外币': 'KHK0QMWB', '增加数量': 'KHK0ZJSL', '增加外币': 'KHK0ZJWB' }
        let dims_str = print_dims(dict, dims, m_Dim)
        let sql = gen_sql(dict, dims, m_Dim)
        let final_str = [dims_str, '\n', '```sql', sql, '```'].join('\n');
        return { dims_str, sql, final_str };
    }

    async function getKpiDataByCode(kpiCode) {
        const token = getCookie('Omp-Prod-Access-Token');
        return await fetch(`https://kpi.dsp.sinopec.com/kpi-web/api/kpiDefine/selectByKpiCode?kpiCode=${kpiCode}`, {
            method: 'GET',
            headers: {
                'Content-Type': 'application/json;charset=UTF-8',
                'authorization': `Bearer ${token}`,
            },
        }).then(response => {
            return response.json();
        }).then(json => {
            // console.log('selectByKpiCode:', json);
            return json.data;
        });
    }

    // 获取特定名称的Cookie值
    function getCookie(name) {
        const value = `; ${document.cookie}`;
        const parts = value.split(`; ${name}=`);
        if (parts.length === 2) return parts.pop().split(';').shift();
    }


})();